/*!\file main.cpp
*/
/*!\mainpage Program "comparison_ordered_trees"
*\section intro_sec Short description of the program
* Program "comparison_ordered_trees" is designed to find the greatest common parts of the two ordered trees.
* The program can be adapted for comparing, editing, search certain parts.
*/
#include <QtCore/QCoreApplication>
#include <QTextCodec>
#include <conio.h>
#include "func.h"
/*!\ fn int main(int argc, char *argv[])
*\ brief The main function to compare two ordered trees and preserve the common and different parts of.
*\ pre User must specify two arguments on the command line: the first - the name of an existing file that contains the first tree,
the second - the name of an existing file that contains a second tree/
*\ post Function generates the common and different parts of the two ordered trees in accordance with the data in the two existing files first and second trees.
If there are mistakes of formalization of data or some error situations in data programm will correctly stop working and will show the message of error.
*\subsection diagramm Hierarchy of functions calling
*The main function uses some functions, description of these functions is also given in documentation.
*/
int main(int argc, char *argv[])
{
	QTextCodec*tc = QTextCodec::codecForName("CP1251");//Set the russian codec for strings
	QTextCodec::setCodecForCStrings(tc);
	QString first_file_cmd;//string for the name of the first file
	QString second_file_cmd;//string for the name of the second file
	QString str_tree1;//string for the data of the first tree
	QString str_tree2;//string for the data of the second tree
	dataAboutTrees* trees;//data structure that contains information about the trees
	QVector <node*> common;//vector of the common parts
	QVector <node*> diff_tree1;//vector different from the common parts of the first tree
	QVector <node*> diff_tree2;//vector different from the common parts of the second tree
	bool ok;//flag
	//checking the number of arguments in command line
	if(argc == 1)
	{
		printf("Error!Not specified files with trees!\n");
		printf("You must specify two files with trees!\n");
		return 0;
	}
	else if(argc == 2)
	{
		printf("Error!No text file!\n");	
		printf("You must specify two files with trees!\n");
	}
	//checking file formats
	first_file_cmd = argv[1];
	second_file_cmd = argv[2];
	if(first_file_cmd.mid(first_file_cmd.size()-4, 4) != ".txt")
	{
		printf("Error!The first file is not a text!\n");
		return 0;
	}
	if(second_file_cmd.mid(second_file_cmd.size()-4, 4) != ".txt")
	{
		printf("Error!The second file is not a text!\n");
		return 0;
	}
	QFile first_file(first_file_cmd);
	QFile second_file(second_file_cmd);
	//Checking the existing of two files with specified names
	if(!first_file.exists())
	{
		printf("File %s doesn't exist\n", argv[1]);
		return 0;
	}
	if(!second_file.exists())
	{
		printf("File %s doesn't exist\n", argv[2]);
		return 0;
	}
	//Reading data from files
	if(!readFile(str_tree1, str_tree2, first_file, second_file))
	{
		printf("Can't open files for reading data!\n");
		return 0;
	}
	/* Prepare the data, the construction of the trees on the basis of lines.
	If there are any suitable error message will be displayed*/
	try
	{
		trees = preparationOfData(str_tree1, str_tree2);
	}
	catch(exception errors)
	{
		switch(errors.type)
		{
			//Error occurs if children do not have a parent
			case no_parent:
				printf("Error in %s! No parent node in the group (%s)!\n", 
						errors.value[0].toAscii().data(), errors.value[1].toAscii().data());
				break;
			//Error occurs if there are empty parentheses in the string
			case empty:
				printf("Error in %s! Empty parentheses! No children at %s node!\n",
						errors.value[0].toAscii().data(), errors.value[1].toAscii().data());
				break;
			//Error occurs if there is no matching closing parenthesis 
			case no_closing:
				printf("Error in %s! No closing parenthesis to parenthesis after %s node!\n",
						errors.value[0].toAscii().data(), errors.value[1].toAscii().data());
				break;
			//Error occurs if there is no matching opening parenthesis
			case no_opening:
				printf("Error in %s! No opening parenthesis to parenthesis after %s node!\n",
						errors.value[0].toAscii().data(), errors.value[1].toAscii().data());
				break;
			//Error occurs if there are unmatched parentheses
			case open_close:
				printf("Error in %s! There are unpaired parentheses at %s node!\n",
						errors.value[0].toAscii().data(), errors.value[2].toAscii().data(), errors.value[1].toAscii().data());
				break;
			//Error occurs if there are repeating nodes
			case unordered_tree:
				printf("Error in %s! Unordered tree! ", errors.value[0].toAscii().data());
				for(int i = 1; i < errors.value.size(); i++)
				{
					errors.value[i].toInt(&ok);
					if(ok && i != 1)
						printf(", ");
					else
						printf(" ");
					printf("%s", errors.value[i].toAscii().data());
				}
				printf(" repeated!\n");
				break;
			//Error occurs if there is a null node
			case zero:
				printf("Error in %s! Unordered tree! Node 0 is invalid. Node > 0! \n",
						errors.value[0].toAscii().data());
				break;
			//Error occurs if there are invalid characters
			case symbol:
				printf("Error in %s! ",errors.value[0].toAscii().data());
				for(int i = 1; i < errors.value.size(); i++)
				{
					printf("\'%s\'", errors.value[i].toAscii().data());
					if(i+1 < errors.value.size())
						printf(", ");
					else
						printf(" - invalid symbol");
				}
				if(errors.value.size() > 2)
					printf("s");
				printf("\n");
				break;
			//Error occurs if there are several opening parentheses
			case several_opening:
				printf("Error in %s! Several opening parentheses after %s node!\n",
						errors.value[0].toAscii().data(), errors.value[1].toAscii().data());
				break;
			//Error occurs if there is no tree in the string
			case no_tree:
				printf("Error in %s! No tree!\n", errors.value[0].toAscii().data());
				break;
			//Error occurs there are several trees in the string
			case several_trees:
				printf("Error in %s! Several trees!\n", errors.value[0].toAscii().data());
				break;
		}
		getch();
		return 0;
	}
	//finding common parts of trees
	common = searchLCP(*trees);
	//forming on the basis of different parts of the first tree
	formLDP(trees->tree1->root, diff_tree1);
	//forming on the basis of different parts of the second tree
	formLDP(trees->root_tree2, diff_tree2);
	//writing the result into file "result.txt"
	writeFile(common, diff_tree1, diff_tree2);
	//message after the completion of the program
	printf("The program is completed. The result stored in the file \"result.txt\" \n");	
	getch();
	return 0;
}

